package postlogic

import (
	"context"

	"go-zero-admin/apps/system/cmd/rpc/internal/svc"
	"go-zero-admin/apps/system/cmd/rpc/syspb"
	"go-zero-admin/pkg/constant"
	"go-zero-admin/pkg/tool"
	"go-zero-admin/pkg/xerr"

	"github.com/Masterminds/squirrel"
	"github.com/jinzhu/copier"
	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
)

type GetPostListLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewGetPostListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPostListLogic {
	return &GetPostListLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *GetPostListLogic) GetPostList(in *syspb.GetPostListReq) (*syspb.GetPostListResp, error) {
	listWhereBuilder := l.svcCtx.SysPostModel.RowBuilder()
	countWhereBuilder := l.svcCtx.SysPostModel.CountBuilder("1")
	if in.GetPostName() != "" {
		condition := squirrel.Eq{"post_name": in.GetPostName()}
		listWhereBuilder = listWhereBuilder.Where(condition)
		countWhereBuilder = countWhereBuilder.Where(condition)
	}
	if in.GetPostCode() != "" {
		condition := squirrel.Eq{"post_code": in.GetPostCode()}
		listWhereBuilder = listWhereBuilder.Where(condition)
		countWhereBuilder = countWhereBuilder.Where(condition)
	}
	if in.GetStatus() != "" {
		condition := squirrel.Eq{"status": in.GetStatus()}
		listWhereBuilder = listWhereBuilder.Where(condition)
		countWhereBuilder = countWhereBuilder.Where(condition)
	}
	if in.GetIsNotId() != 0 {
		condition := squirrel.NotEq{"post_id": in.GetIsNotId()}
		listWhereBuilder = listWhereBuilder.Where(condition)
		countWhereBuilder = countWhereBuilder.Where(condition)
	}
	if in.GetIsExCodeOrName() || in.GetPostName() != "" || in.GetPostCode() != "" {
		condition := squirrel.Or{
			squirrel.Eq{"post_name": in.GetPostName()},
			squirrel.Eq{"post_code": in.GetPostCode()},
		}
		listWhereBuilder = listWhereBuilder.Where(condition)
		countWhereBuilder = countWhereBuilder.Where(condition)
	}
	if len(in.GetIds()) != 0 {
		condition := squirrel.Eq{"post_id": in.GetIds()}
		listWhereBuilder = listWhereBuilder.Where(condition)
		countWhereBuilder = countWhereBuilder.Where(condition)
	}

	// 查询
	if in.GetPage() != nil && in.GetPage().GetIsPage() {
		return l.getPage(in, listWhereBuilder, countWhereBuilder)
	} else if in.GetPage() != nil && in.GetPage().GetIsCount() {
		return l.getCount(in, countWhereBuilder)
	}
	return l.getList(in, listWhereBuilder)
}

func (l *GetPostListLogic) getList(in *syspb.GetPostListReq,
	whereBuilder squirrel.SelectBuilder) (*syspb.GetPostListResp, error) {
	orderBy := "post_sort,post_id asc"
	if in.GetPage() != nil {
		orderBy = in.GetPage().GetOrderBy()
	}
	list, err := l.svcCtx.SysPostModel.FindAll(l.ctx, whereBuilder, orderBy)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DbError),
			tool.GetErrMsgFormat("get post list"), err, in)
	}

	// 数据转换
	var dataList []*syspb.SysPost
	for _, v := range list {
		var data syspb.SysPost
		_ = copier.Copy(&data, v)

		data.UpdateTime = v.UpdateTime.Unix()
		data.CreateTime = v.CreateTime.Unix()

		dataList = append(dataList, &data)
	}

	return &syspb.GetPostListResp{
		List: dataList,
	}, nil
}

func (l *GetPostListLogic) getPage(in *syspb.GetPostListReq, listWhereBuilder squirrel.SelectBuilder,
	countWhereBuilder squirrel.SelectBuilder) (*syspb.GetPostListResp, error) {
	// 分页条件
	pageNum := in.GetPage().GetPageNum()
	if pageNum == 0 {
		pageNum = 1
	}
	pageSize := in.GetPage().GetPageSize()
	if pageSize == 0 {
		pageSize = constant.PageSize
	}
	orderBy := in.GetPage().GetOrderBy()
	if orderBy == "" {
		orderBy = "post_sort,post_id asc"
	}

	// 分页查询
	list, err := l.svcCtx.SysPostModel.FindPageListByPage(l.ctx, listWhereBuilder, pageNum, pageSize, orderBy)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DbError),
			tool.GetErrMsgFormat("get post list"), err, in)
	}
	count, err := l.svcCtx.SysPostModel.FindCount(l.ctx, countWhereBuilder)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DbError),
			tool.GetErrMsgFormat("get post count"), err, in)
	}

	// 处理数据
	var dataList []*syspb.SysPost
	for _, v := range list {
		var data syspb.SysPost
		_ = copier.Copy(&data, v)

		data.UpdateTime = v.UpdateTime.Unix()
		data.CreateTime = v.CreateTime.Unix()

		dataList = append(dataList, &data)
	}

	return &syspb.GetPostListResp{
		List: dataList,
		Page: &syspb.PageResp{
			Current: pageNum,
			Total:   count,
		},
	}, nil
}

func (l *GetPostListLogic) getCount(in *syspb.GetPostListReq, whereBuilder squirrel.SelectBuilder) (*syspb.GetPostListResp, error) {
	count, err := l.svcCtx.SysPostModel.FindCount(l.ctx, whereBuilder)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DbError),
			tool.GetErrMsgFormat("get post count"), err, in)
	}

	return &syspb.GetPostListResp{
		Page: &syspb.PageResp{
			Total: count,
		},
	}, nil
}
